<?php

namespace paymch\components\wechat;

use Yii;
use yii\web\NotAcceptableHttpException;
use yii\base\Exception;

/**
 * 数据对象基础类，该类中定义数据类最基本的行为，包括：
 * 计算/设置/获取签名、输出xml格式的参数、从xml读取数据对象等
 * @author emhome
 */
class HttpDataFormatter extends \yii\base\Component {

    public $partner_key = '';
    protected $values = [];

    /**
     * 获取签名，详见签名生成算法的值
     * @return 值
     * */
    public function getSign() {
        return $this->values['sign'];
    }

    /**
     * 格式化参数格式化成url参数
     */
    public function toUrlParams() {
        $buff = "";
        foreach ($this->values as $k => $v) {
            if ($k != "sign" && $v != "" && !is_array($v)) {
                $buff .= $k . "=" . $v . "&";
            }
        }
        $buff = trim($buff, "&");
        return $buff;
    }

    /**
     * 生成签名
     * @return 签名，本函数不覆盖sign成员变量，如要设置签名需要调用SetSign方法赋值
     */
    public function generateSignature() {
        //签名步骤一：按字典序排序参数
        ksort($this->values);
        $string = $this->toUrlParams();
        //签名步骤二：在string后加入KEY
        $string = $string . "&key=" . $this->partner_key;
        //签名步骤三：MD5加密
        $string = md5($string);
        //签名步骤四：所有字符转为大写
        $result = strtoupper($string);
        return $result;
    }

    /**
     * 获取设置的值
     */
    public function getValues() {
        return $this->values;
    }

    /**
     * 获取设置的值
     */
    public function setValues($values) {
        return $this->values = $values;
    }

    /**
     * 签名校验
     */
    public function checkSignature($values) {
        $this->setValues($values);
        $sign = $this->generateSignature();
        return $sign === $this->sign;
    }

    /**
     * 输出xml字符
     * @throws WxPayException
     * */
    public static function toXml($data) {
        if (empty($data)) {
            $data = [
                'return_code' => 'FAIL',
                'return_msg' => date('Y-m-d H:i:s') . ' [ASYNCNOTIFY] Unknown error.'
            ];
        }

        $xml = "<xml>";
        foreach ($data as $key => $val) {
            if (is_numeric($val)) {
                $xml .= "<" . $key . ">" . $val . "</" . $key . ">";
            } else {
                $xml .= "<" . $key . "><![CDATA[" . $val . "]]></" . $key . ">";
            }
        }
        $xml .= "</xml>";
        return $xml;
    }

    /**
     * 将xml转为array
     * @param string $xml
     * @throws WxPayException
     */
    public static function fromXml($string) {
        if (empty($string)) {
            return false;
        }
        try {
            $xml = @simplexml_load_string($string, 'SimpleXMLElement', LIBXML_NOCDATA);
        } catch (Exception $e) {
            Yii::error([
                'data' => $string,
                'errmsg' => $e->getMessage(),
            ]);
            return false;
        }
        if ($xml) {
            return json_decode(json_encode($xml), true);
        }
        return false;
    }

}
